#ifndef GEOMETRICUTIL_H
#define GEOMETRICUTIL_H

/**
 * @file geometricutil.h
 * @author your name (you@domain.com)
 * @brief 几何计算
 * @version 0.1
 * @date 2023-11-21
 *
 * @copyright Copyright (c) 2023
 *
 */

// #include "CommonUtils_global.h"
#include <QPointF>
#include <QVector>
#include <QRect>

namespace ns_yht
{

    class /*COMMONUTILS_EXPORT*/ GeometricUtil
    {
    public:
        GeometricUtil();

        /**
         * @brief SimplifyLine 精简一组连续点（线条），距离很近的点合成一个点，坐标为像素点
         * @param spoints   输入点数组（输入线条）
         * @param dpoints   输出点数组（输出线条）
         * @param dis       误差阈值
         */
        static void simplifyLine(const QVector<QPointF> &spoints, QVector<QPointF> &dpoints, double dis = 5.0);

        static QRect normalizeRectangle(double x1, double y1, double x2, double y2);
        static QRect normalizeRectangle(const QPointF &pt1, const QPointF &pt2);

        static QPointF rotateOnePoint(const QPointF &o, double alpha, const QPointF &p);
        // static wxRealPoint* RotatePoint(wxRealPoint ptBase, float changedAngle, wxRealPoint* pts,int nptCount);
        static double getAngle(const QPointF &pt0, const QPointF &pt1);
        static double getAngleNorth(const QPointF &pt0, const QPointF &pt1);
        static QPointF getPtInAngle(QPointF &ptBase, double angle, double distance);
        static double getNormalizedAngle(double angle, int normalizedType);
        static double getTwoLinesAngle(const QPointF &o, const QPointF &s, const QPointF &e);
        static double getDistance(const QPointF &pt1, const QPointF &pt2);
        static double getDistance(QPoint pt1, QPoint pt2);
        static double getDistance(double x1, double y1, double x2, double y2);
        static double getPtToLineDistance(const QPointF &a, const QPointF &b, const QPointF &s);
        static double getPtToLineDistance(double ax, double ay, double bx, double by, const QPointF &s);
        static bool isPointInLine(const QPointF &pt1, const QPointF &pt2, const QPointF &pt3);
        static bool isPointInPoly(int nvert, QPointF *poly, const QPointF &point, bool judgeInMaxMin);
        static bool isPointInPoly(const QVector<QPointF> &poly, const QPointF &point, bool judgeInMaxMin);
        static int isPtInEllipse(double x1, double y1, double x2, double y2, double x, double y);
        /**
         * @brief dist2d 两个点之间的几何距离
         * @param pt1
         * @param pt2
         * @return
         */
        static double dist2d(const QPointF &pt1, const QPointF &pt2);

        /**
         * @brief 获取平行线
         *
         * @param line
         * @param offset    距离
         * @param isLeft    是否左边
         * @param outLine
         */
        static void parallelLine(QVector<QPointF> &line, double offset, bool isLeft, QVector<QPointF> &outLine);

        /**
         * @brief 获取平行线
         *
         * @param pt1
         * @param pt2
         * @param offset    距离
         * @param isLeft    是否左边
         * @param outPoint1
         * @param outPoint2
         */
        static void parallelLine(const QPointF &pt1, const QPointF &pt2, double offset, bool isLeft, QPointF &outPt1, QPointF &outPt2);

        static bool equals(const QPointF &pt1, const QPointF &pt2);

        static bool intersectsOfPolyPoly(const QVector<QPointF> &poly1, const QVector<QPointF> &poly2);
        static bool intersectsOfPolyLine(const QVector<QPointF> &poly, const QVector<QPointF> &line);

    public:
        static const double MYPI;         //=3.14159265359;	    // PI
        static const double PI2;          //=6.28318530718;	// PI*2
        static const double PID2;         //=1.570796326795;	// PI/2
        static const double PI3D2;        //=4.712388980385; // PI*3/2
        static const double DPPi;         //=57.295779513;	// 180/PI
        static const double PiPD;         //=0.01745329252;	// PI/180
        static const double EARTH_RADIUS; //=6378.137;   //地球半径，单位：公里
    };

} // namespace ns_yht

#endif // GEOMETRICUTIL_H
